package com.database.daos.imp;

import java.sql.*;

import javax.sql.DataSource;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;

import com.database.daos.IMaxDao;
import com.database.objects.*;

public class MaxDao extends GenericDao<Double> implements IMaxDao {

	private static final long serialVersionUID = 5111074805108887099L;

	private SimpleJdbcTemplate jdbcTemplate;

	@Override
	public Double getMaxCyclomaticByDeveloperAndDateAndTypeAndStatus(Developer developer, String date, Type type, Status status) {
		RowMapper<Double> mapper = new RowMapper<Double>() {
			@Override
			public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
				double max = rs.getDouble("max");
				return max;
			}
		};

		String query = "";
		String queryTotal = "";
		if (type.isCommit()) {
			query = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and com_status = ?";
			queryTotal = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and com_status != 'UNKNOWN'";
		} else if (type.isFileOO()) {
			query = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and fil_status = ?";
			queryTotal = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and fil_status != 'UNKNOWN'";
		} else if (type.isClass()) {
			query = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and cla_status = ?";
			queryTotal = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and cla_status != 'UNKNOWN'";
		} else if (type.isMethod()) {
			query = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and met_status = ?";
			queryTotal = "select max(met_cyclomatic) as max from method natural inner join class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and met_status != 'UNKNOWN'";
		}

		if (!query.equals("") && !queryTotal.equals("")) {
			if (status.isTotal()) {
				return jdbcTemplate.queryForObject(queryTotal, mapper, developer.getId(), date);
			} else {
				return jdbcTemplate.queryForObject(query, mapper, developer.getId(), date, status.toString());
			}
		}
		return 0.0;
	}

	@Override
	public Double getMaxConstantineCohesionByDeveloperAndDateAndTypeAndStatus(Developer developer, String date, Type type, Status status) {
		RowMapper<Double> mapper = new RowMapper<Double>() {
			@Override
			public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
				double max = rs.getDouble("max");
				return max;
			}
		};

		String query = "";
		String queryTotal = "";
		if (type.isCommit()) {
			query = "select max(cla_constantine_cohesion) as max from class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and com_status = ?";
			queryTotal = "select max(cla_constantine_cohesion) as max from class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and com_status != 'UNKNOWN'";
		} else if (type.isFileOO()) {
			query = "select max(cla_constantine_cohesion) as max from class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and fil_status = ?";
			queryTotal = "select max(cla_constantine_cohesion) as max from class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and fil_status != 'UNKNOWN'";
		} else if (type.isClass()) {
			query = "select max(cla_constantine_cohesion) as max from class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and cla_status = ?";
			queryTotal = "select max(cla_constantine_cohesion) as max from class natural inner join file natural inner join commit where dev_id = ? and com_date = ? and cla_status != 'UNKNOWN'";
		}

		if (!query.equals("") && !queryTotal.equals("")) {
			if (status.isTotal()) {
				return jdbcTemplate.queryForObject(queryTotal, mapper, developer.getId(), date);
			} else {
				return jdbcTemplate.queryForObject(query, mapper, developer.getId(), date, status.toString());
			}
		}
		return 0.0;
	}

	@Override
	public Double getMaxCyclomaticContributionsByDeveloperAndTypeAndStatus(Developer developer, Type type, Status status, String start, String finish) {
		RowMapper<Double> mapper = new RowMapper<Double>() {
			@Override
			public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
				double max = rs.getDouble("max");
				return max;
			}
		};

		String query = "select max(con_cyclomatic) as max from contribution where dev_id = ? and con_type = ? and con_status = ? and con_date >= ? and con_date < ?";
		return jdbcTemplate.queryForObject(query, mapper, developer.getId(), type.toString(), status.toString(), start, finish);
	}

	@Override
	public Double getMaxCyclomaticContributionsByProjectAndTypeAndStatus(Project project, Type type, Status status, String start, String finish) {
		RowMapper<Double> mapper = new RowMapper<Double>() {
			@Override
			public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
				double max = rs.getDouble("sum");
				return max;
			}
		};

		String query = "select sum(contributions.max) as sum from developer dev inner join (select dev_id, max(con_cyclomatic) as max from contribution natural inner join developer where con_type = ? and con_status = ? and con_date >= ? and con_date < ? group by dev_id) contributions on contributions.dev_id = dev.dev_id where pro_name = ?";
		return jdbcTemplate.queryForObject(query, mapper, type.toString(), status.toString(), start, finish, project.getName());
	}

	@Override
	public Double getMaxCohesionContributionsByDeveloperAndTypeAndStatus(Developer developer, Type type, Status status, String start, String finish) {
		RowMapper<Double> mapper = new RowMapper<Double>() {
			@Override
			public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
				double max = rs.getDouble("max");
				return max;
			}
		};

		String query = "select max(con_constantine_cohesion) as max from contribution where dev_id = ? and con_type = ? and con_status = ? and con_date >= ? and con_date < ?";
		return jdbcTemplate.queryForObject(query, mapper, developer.getId(), type.toString(), status.toString(), start, finish);
	}

	@Override
	public Double getMaxCohesionContributionsByProjectAndTypeAndStatus(Project project, Type type, Status status, String start, String finish) {
		RowMapper<Double> mapper = new RowMapper<Double>() {
			@Override
			public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
				double max = rs.getDouble("sum");
				return max;
			}
		};

		String query = "select sum(contributions.max) as sum from developer dev inner join (select dev_id, max(con_constantine_cohesion) as max from contribution natural inner join developer where con_type = ? and con_status = ? and con_date >= ? and con_date < ? group by dev_id) contributions on contributions.dev_id = dev.dev_id where pro_name = ?";
		return jdbcTemplate.queryForObject(query, mapper, type.toString(), status.toString(), start, finish, project.getName());
	}

	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
	}

}